# @Time   : 2022-03-03 17:00:00
# @Author : Gavin Jiang
# @Owner  : YSRD (Insights Value)
# 统一 规范式  接口  框架
import logging.config
import os
import traceback
import pymysql
pymysql.install_as_MySQLdb()

import yaml
from flask import Flask, Response
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy

from framework.bootstrap.config_loader import ConfigLoader
from framework.bootstrap.register_router import RegisterRouter
from framework.interceptor.interceptor_loader import InterceptorLoader
from framework.the_path import ThePath

def _init_interceptor(app: Flask):
    """
    注册拦截器
    @param app:
    @return:
    """
    before_list, after_list = InterceptorLoader.load_interceptors()

    @app.before_request
    def before_request():
        for instance in before_list:
            try:
                instance.handle()
            except Exception as e:
                logging.error(f"执行before拦截器失败:\n{instance.__class__}，捕获异常：\n{traceback.format_exc()}")
                return str(e)

    @app.after_request
    def after_request(resp: Response):
        for instance in after_list:
            try:
                resp = instance.handle(resp)
            except Exception:
                logging.error(f"执行after拦截器失败:\n{instance.__class__}，捕获异常：\n{traceback.format_exc()}")

        return resp


def _set_logging(log_config_path):
    # 查找log文件夹，如果不存在则自动创建
    ThePath.tmp('log')
    with open(log_config_path) as f:
        config = yaml.load(f, Loader=yaml.FullLoader)
        config['handlers']['timed_rotating_file']['filename'] = os.path.join(ThePath.tmp('log'), 'api.log')
        logging.config.dictConfig(config)


def _init(env=None):
    config_loader = ConfigLoader(env)
    config_loader.load()

    _set_logging(config_loader.data.get('log'))

    app = Flask(__name__)

    app.config.from_pyfile(config_loader.data.get('flask'))

    _init_interceptor(app)

    RegisterRouter().register_router(app)

    CORS(app, supports_credentials=True)
    sql_alchemy = SQLAlchemy(app)

    app.config['_SQLALCHEMY_INSTANCE'] = sql_alchemy
    print('env:', config_loader.env)
    return app


create_app = _init


def startup(env):
    app = _init(env)

    print(app.url_map)
    app.run(host=app.config['HOST'], port=app.config['PORT'])


if __name__ == '__main__':
    startup('dev')

